package com.breadenglish.cms.api.app.sys.service.impl;

import com.breadenglish.cms.api.app.dao.CodeDao;
import com.breadenglish.cms.api.app.domain.constants.Constants;
import com.breadenglish.cms.api.app.domain.constants.MessageConstants;
import com.breadenglish.cms.api.app.domain.db.Code;
import com.breadenglish.cms.api.app.domain.exception.BusinessException;
import com.breadenglish.cms.api.app.domain.query.CodeQuery;
import com.breadenglish.cms.api.app.sys.service.CodeService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * 字典服务器实现
 * User: guoyao
 * Date: 13-12-17
 * Time: 下午4:52
 */
@Service("codeService")
public class CodeServiceImpl implements CodeService {

    private final static Logger logger = LoggerFactory.getLogger(CodeServiceImpl.class);

    @Resource
    private CodeDao codeDao;

    /**
     * 查询字典列表
     * @param code 字典信息
     * @return 字典信息集合
     */
    public List<Code> queryCodes(Code code) throws Throwable {
        return codeDao.select(code);
    }

    /**
     * 查询字典详情
     * @param code 字典信息
     * @return 字典详情
     */
    public CodeQuery queryCode(Code code) throws Throwable{
        return codeDao.selectByPrimaryKey(code);
    }

    /**
     * 查询字典及字典分类信息
     * @param code 字典信息
     * @return 字典信息集合
     */
    public List<CodeQuery> selectCodeAndClass(CodeQuery code) throws Throwable {
        return codeDao.selectCodeAndClass(code);
    }

    /**
     *  查询字典树
     * @param code 字典信息
     * @return  字典信息结合
     */
    public List<Code> queryCodeTree(Code code) throws Throwable {
        return codeDao.queryCodeTree(code);
    }

    /**
     * 添加字典信息
     * @param code 字典信息
     * @return 影响行数
     */
    public void insertCode(Code code) throws Throwable {

        // 字典信息(codeId, classId)唯一性验证
        uniqueCode(code.getClassId(), code.getCodeId().toString());
        code.setCreateTime(new Date());
        int result = codeDao.insert(code);
        if(result != 1){
            logger.debug("新增字典信息失败，准备抛出异常");
            BusinessException businessException = new BusinessException();
            businessException.setCode(MessageConstants.INSERT_CODE_FAIL);
            throw businessException;
        }
    }

    /**
     * 根据字典ID更新字典信息
     * @param code 字典信息
     * @return 影响行数
     */
    public void updateCode(Code code) throws Throwable {
        Date now = new Date();
        code.setUpdateTime(now);
        int result = codeDao.update(code);
        if(result != 1){
            BusinessException businessException = new BusinessException();
            businessException.setCode(MessageConstants.UPDATE_CODE_FAIL);
            throw businessException;
        }
    }

    /**
     * 根据字典ID删除字典信息
     * @param code 字典ID
     *               resultMap 删除结果信息
     *               codeId      要删除的codeId组合字符串
     *               classId     要删除的classId组合字符串
     * @return 影响行数
     */
    public void deleteCode(Code code,String codeId,String classId) throws Throwable {
        // TODO 批量删除字符串分隔符 X
        String[] codeIds = codeId.split(":");
        // TODO 批量删除字符串分隔符 X
        String[] classIds= classId.split(":");
        int idLen = codeIds.length;
        logger.debug("codeIds.length => " + idLen);

        List<String[]> errors = new ArrayList<String[]>();

        if(idLen == 0 ){
            BusinessException businessException = new BusinessException();
            businessException.setCode(MessageConstants.DELETE_CODE_UNSELECTED);
            throw businessException;
        }
        int sucNum = 0;
        code.setDelTag(Constants.YES);
        code.setUpdateTime(new Date());

        String[] errorMsg = new String[2];
        // TODO 删除结果提示信息，采用占位符替换方法 X
        errorMsg[0] = "失败ID: \n";

        for(int i = 0; i < idLen; i++){
            code.setClassId(classIds[i]);
            code.setCodeId(Long.parseLong(codeIds[i]));
            logger.debug("classId => " + classIds[i] + " codeId => " + codeIds[i] );
            int result = codeDao.update(code);

            if (result == 0){
                errorMsg[0] = errorMsg[0] + "  \t " + codeIds[i] + "\n";
            }

            sucNum += result;
        }

        if(sucNum != idLen){
            BusinessException businessException = new BusinessException();
            if (sucNum < idLen && sucNum > 0) {
                errorMsg[1] = "成功删除: " + sucNum + " 条 \n";
            }

            if (sucNum > idLen) {
                errorMsg[1] = "预期删除: " + idLen + " 条, 实际删除: " + sucNum + " 条\n";
            }
            if (sucNum == 0) {
                errorMsg[1] = "\n删除失败";
            }
            errors.add(errorMsg);
            businessException.setKeys(errors);
            businessException.setCode(MessageConstants.DELETE_FAIL);
            throw businessException;
        }
    }

    /**
     * 验证字典唯一性
     * @param classId 分类ID
     *               codeId 字典ID
     * @return 统计结果
     */
    public void uniqueCode(String classId, String codeId)  throws Throwable {
        Map<String, Object> param = new HashMap<String, Object>();
        // TODO 参数采用对象形式 X
        param.put("codeId",Long.parseLong(codeId));
        param.put("classId",classId);
        int result = codeDao.uniqueCode(param);
        if(result > 0){
            logger.debug("验证字典信息唯一性错误，准备抛出异常");
            BusinessException businessException = new BusinessException();
            businessException.setCode(MessageConstants.CODE_UNIQUE_CHECK_FAIL);
            throw businessException;
        }
    }
}
